package com.mq.java.test;

import com.mq.common.MqConnectionUtils;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zhanghaidong
 * @version v1.0
 * @description
 * @date 2019/8/19
 *
 *
 * DLX
 *    Dead Letter Exchange 的缩写
 *    DLX也叫死信邮箱（网上的译法），死信交换机（字面翻译）。归根结底就是一个交换机，当队列中出现死信时，通过这个交换机将死信重新发送到
 *    死信队列中（指定好rabbitmq会自动发送）。
 *
 * 什么是死信呢？官方给出三个说法：
 *    消息被拒绝（basic.reject或basic.nack）并且requeue=false.
 *    消息TTL过期
 *    队列达到最大长度（队列满了，无法再添加数据到mq中）
 *
 * 什么是死信交换机
 *    在定义业务队列的时候，要考虑指定一个死信交换机，死信交换机可以和任何一个普通的队列进行绑定，然后在业务队列出现死信的时候就会将数据发送到死信队列。
 *
 *
 * 什么是死信队列
 *     死信队列实际上就是一个普通的队列，只是这个队列跟死信交换机进行了绑定，用来存放死信而已。
 *
 * 如何使用死信交换机
 *     定义业务（普通）队列的时候指定参数
 *          x-dead-letter-exchange: 用来设置死信后发送的交换机
 *          x-dead-letter-routing-key：用来设置死信的routingKey
 *
 */
public class ProducerDeadExchange {

    public static void main(String[] args) {

        try{
            Connection connection = MqConnectionUtils.getConnection();
            Channel channel = connection.createChannel();

            // 定义死信队列
            channel.queueDeclare("dead-queue", true, false, false, null);
            // 定义死信交换器
            channel.exchangeDeclare("dead_letter_exchange",
                    BuiltinExchangeType.FANOUT,
                    false,
                    false,
                    false,
                    null);
            // 绑定死信队列和死信交换器
            channel.queueBind("dead-queue", "dead_letter_exchange", "dead-routingKey", null);

            //====================================================================================================================

            //定义业务交换器
            channel.exchangeDeclare("business-exchange",
                    BuiltinExchangeType.FANOUT,
                    false,
                    false,
                    false,
                    null);

            Map<String, Object> map = new HashMap<>(2);
            //设置死信交换机
            map.put("x-dead-letter-exchange", "dead_letter_exchange");
            //设置死信routingKey
            map.put("x-dead-letter-routing-key", "dead-routingKey");
            // 消息失效时间20秒
            map.put("x-message-ttl", 2000);
            // 定义业务队列
            channel.queueDeclare("business-queue", false, false, false, map);

            // 绑定业务交换器和业务队列
            channel.queueBind("business-queue", "business-exchange", "business-routingKey", null);




            channel.close();
            connection.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
